感謝 iT 邦幫忙與博碩文化,本系列文章已出版成書「從 Hooks 開始,讓你的網頁 React 起來」,首刷版稅將全額贊助 iT 邦幫忙鐵人賽,歡迎前往購書,鼓勵筆者撰寫更多優質文章。
昨天我們複習了在 React 中一定會用到的 JavaScript 語法,不知道昨天的內容會不會有點吃不消呢?可以在底下留言告訴我,如果喜歡我們的頻道,不要忘了按讚、分享、訂閱,還要開啟小鈴鐺喔。
今天我們先來用原生的 JavaScript 來完成一個簡單的計數器!之後幾天會再把這個計數器改成用 React 來寫,讓你感受一下兩者的差別,體會 React 幫前端工程師解決了什麼樣的痛點。
現在我們先來用 CodePen 完成一個簡單計數器的畫面,這個計數器的畫面是由 Oleg Frolov 所設計,並放置於 dribble 上。
首先在 HTML 的部分可以複製下面的程式碼,這個部分的內容很簡單,三個 div
區塊分別對應到畫面上的「向上箭頭」、「數字」、「向下箭頭」:
<!-- HTML -->
<div class="container">
<!-- 向上箭頭 -->
<div class="chevron chevron-up"></div>
<!-- 數字 -->
<div class="number">
256
</div>
<!-- 向下箭頭 -->
<div class="chevron chevron-down"></div>
</div>
接著在 CSS 的部分可以貼上:
/* CSS */
/**
* Credit:
* counter design is from dribbble (https://dribbble.com/shots/5539678-Stepper-VI)
* chevron icons are from fontAwesome (https://fontawesome.com/icons/chevron-down?style=solid)
**/
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
background-color: #f26072;
display: flex;
align-items: center;
justify-content: center;
}
.container {
display: flex;
align-items: center;
flex-direction: column;
}
.number {
font-size: 72px;
color: #fbf5f5;
font-family: Verdana;
line-height: 1.75em;
text-align: center;
user-select: none;
}
.chevron {
background: transparent center center;
background-repeat: no-repeat;
cursor: pointer;
width: 70px;
height: 70px;
transition: all 0.3s;
}
.chevron-up {
background-image: url("data:image/svg+xml, %3Csvg aria-hidden='true' focusable='false' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23f6909c' d='M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z'%3E%3C/path%3E%3C/svg%3E");
}
.chevron-up:hover {
background-image: url("data:image/svg+xml, %3Csvg aria-hidden='true' focusable='false' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23fbf5f5' d='M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z'%3E%3C/path%3E%3C/svg%3E");
}
.chevron-down {
background-image: url("data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23f6909c' d='M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z'%3E%3C/path%3E%3C/svg%3E");
}
.chevron-down:hover {
background-image: url("data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23fbf5f5' d='M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z'%3E%3C/path%3E%3C/svg%3E");
}
這時候你應該就可以看到頁面上出現計數器的畫面。如果你想要用一個「完整的頁面」來檢視目前的畫面,可以在 CodePen 右上方點選「Change View」之後按下「Debug mode」:
這時會跳出一個獨立的頁面,如果有需要 Debug 的話,使用這個 Deubg 頁面較不會被 CodePen 中的其他元素所干擾,因此也更容易找到元素在網頁中的位置:
完成之後按下儲存,這個頁面就會保存在你的 Dashboard 中了。
完成的程式碼和畫面可以看 Day 3 - Counter Started Template @ Codepen。
在這 30 天中主要會著重在 JavaScript 和 React 的應用,所以在 HTML 和 CSS 的部分並不會著墨太多。
現在已經完成了計數器的畫面,接著我們希望當使用者點擊「向上箭頭」的時候數字增加,當使用者點擊「向下箭頭」的時候數字減少,像是這樣的話,可以怎麼做呢?
你可以先花 5 ~ 10 分鐘的時間試著嘗試看看能不能做到上圖的效果,這裡提供幾個關鍵字包括 querySelector
、addEventListener
。如果嘗試了 10 分鐘還沒做出來的話,也不用氣餒,回憶一下你剛剛試著用什麼方法解決這個問題,然後繼續看一下去可以怎麼做。
因為使用者點擊滑鼠的時候要改變數字,所以勢必要去監聽使用者對於「箭頭」的「點擊事件」,因此:
querySelector
去選到「箭頭」的元素(即,upElement
和 downElement
)querySelector
去選到「數字」元素(即,numberElement
)addEventListener
監聽使用者的點擊事件(click
)numberElement.textContent
取得,同時這裡因為取得的數字是字串,所以需先透過 Number()
方法,將字串轉成數值,以便進行加減。currentNumber
)進行加減後,透過 textContent
給回修改後的數字。// JavaScript
// STEP 1: 透過 querySelector 選擇到 HTML 中的「箭頭」元素
const upElement = document.querySelector(".chevron-up");
const downElement = document.querySelector(".chevron-down");
// STEP 2: 透過 querySelector 選擇到 HTML 中的「數字」元素
const numberElement = document.querySelector(".number");
// STEP 3: 監聽 click 事件,並執行對應的行為
upElement.addEventListener("click", e => {
// STEP 4: 取得當前網頁上的數字
const currentNumber = Number(numberElement.textContent);
// STEP 5: 將數字增加後帶回網頁上
numberElement.textContent = currentNumber + 1;
});
downElement.addEventListener("click", e => {
const currentNumber = Number(numberElement.textContent);
numberElement.textContent = currentNumber - 1;
});
如此,就可以在使用者點擊按鈕之後讓計數器產生對應的變化:
完成之後按下儲存,這個頁面就會保存在你的 Dashboard 中了。完成的程式碼和畫面可以看 Day 3 - Finished Counter @ Codepen。
透過 CodePen 的設定,可以將程式編輯的畫面調整成自己偏好的樣式。方式是點擊右上角的頭像後,點選「Setting」:
這裡面可以進行許多不同的偏好設定,你可以選擇喜歡的佈景主題、字型、字體大小、縮排長度等等:
你好,請問一下 background-image: url中的東西是怎麼來的,Dribble有提供嗎?
yumememooo 它就是 SVG 喔!SVG 的原始碼是類似 HTML(確切來說是 XML)的程式碼,所以只是直接把 SVG 的原始碼貼到 background-image 的 url 中。
你好 剛入門寫程式
想請問為什麼currentNumber寫在最外層function裡面只會抓到256
而不是加減過後的數字
是跟作用域有關嗎